﻿using System;
using System.Collections.Generic;

namespace Sunyi.Project.WebPoint.DataAccessController
{
    public sealed class CacheProvider
    {
        private readonly object SyncObject = new object();

        private Dictionary<Type, Dictionary<Guid, object>> cache = new Dictionary<Type, Dictionary<Guid, object>>();

        public static readonly CacheProvider Instance = new CacheProvider();

        internal Dictionary<Guid, object> Get<T>() where T : class
        {
            Type type = typeof(T);
            if (!cache.ContainsKey(type))
            {
                lock (SyncObject)
                {
                    if (!cache.ContainsKey(type))
                    {
                        cache.Add(type, new Dictionary<Guid, object>());
                    }
                }
            }

            return cache[type];
        }

        public T Get<T>(Guid id) where T : class
        {
            Type type = typeof(T);
            if (!cache.ContainsKey(type))
            {
                lock (SyncObject)
                {
                    if (!cache.ContainsKey(type))
                    {
                        cache.Add(type, new Dictionary<Guid, object>());
                    }
                }
            }

            lock (SyncObject)
            {
                if (cache[type].ContainsKey(id)) return cache[type][id] as T;

                return null;
            }
        }

        public void Add<T>(Guid id, object value)
        {
            Type type = typeof(T);
            if (!cache.ContainsKey(type))
            {
                lock (SyncObject)
                {
                    if (!cache.ContainsKey(type))
                    {
                        cache.Add(type, new Dictionary<Guid, object>());
                    }
                }
            }

            lock (SyncObject)
            {
                if (!cache[type].ContainsKey(id)) cache[type].Add(id, value);
            }
        }

        public void Remove<T>(Guid id)
        {
            Type type = typeof(T);
            if (cache.ContainsKey(type))
            {
                lock (SyncObject)
                {
                    if (cache[type].ContainsKey(id)) cache[type].Remove(id);
                }
            }
        }

        public void Clear<T>()
        {
            Type type = typeof(T);
            if (cache.ContainsKey(type))
            {
                lock (SyncObject)
                {
                    cache[type].Clear();
                }
            }
        }

        private CacheProvider() { }
    }
}
